﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.ServiceModel;
using System.Windows;
using System.Windows.Controls;
using System.Xml.Linq;

using LightReader.LightReaderService;
using LightReader.UserService;

namespace LightReader
{
    public partial class MainPage : UserControl
    {
        #region Private vars
        private LightReaderServiceClient _lightReaderServiceProxy;
        private UserServiceClient _userServiceProxy;
        private User _user = null;
        #endregion

        public MainPage()
        {
            InitializeComponent();

            // this makes sure the subscribe/register form is properly displayed
            subscribeForm.Height = App.Current.Host.Content.ActualHeight;
            subscribeForm.Width = App.Current.Host.Content.ActualWidth;
            postGrid.Height = App.Current.Host.Content.ActualHeight * .75;

            setupExternalServices();
            setupEventHandlers();
        }

        public MainPage(User user) : this()
        {
            _user = user;
            loadFeeds();
        }

        #region Event handlers
        void refreshFeedsButton_Click(object sender, RoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        private void unsubscribeFromFeedButton_Click(object sender, RoutedEventArgs e)
        {
            if (subscribedFeedsList.SelectedItem != null)
            {
                LightReader.UserService.Feed selectedFeed = (LightReader.UserService.Feed)subscribedFeedsList.SelectedItem;
                _user.SubscribedFeeds.Remove(selectedFeed);
                postGrid.ItemsSource = null;
                loadFeeds();
            }
        }

        private void importOPMLButton_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog {Filter = "OPML Files (*.opml)|*.opml"};

            if (dlg.ShowDialog() == true)
            {
                using (StreamReader reader = dlg.File.OpenText())
                {
                    string opmlContents = reader.ReadToEnd();
                    if (opmlContents.Length > 0)
                    {
                        _lightReaderServiceProxy.ImportOPMLAsync(opmlContents);
                    }
                }
            }
        }

        void proxy_GetFeedCompleted(object sender, GetFeedCompletedEventArgs e)
        {
            handleFeedData(e.Result);
        }

        private void logoutButton_Click(object sender, RoutedEventArgs e)
        {
            // back to the splash/login screen
            NavigationHelper.Navigate(new SplashPage());
        }

        private void myProfileButton_Click(object sender, RoutedEventArgs e)
        {
            // TODO: display a modified version of the register screen.
        }

        void subscribeForm_SubscriptionAdded(object sender, SubscriptionEventArgs e)
        {
            this.subscribePopup.IsOpen = false;
            // add to the listbox
            LightReader.UserService.Feed f = new LightReader.UserService.Feed();
            f.Name = e.Title;
            f.Url = e.Url;

            addFeedToList(f);
            persistFeed(f);
        }

        private void subscribedFeedsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListBox lbi = (ListBox)sender;
            if (lbi.SelectedItem != null)
            {
                LightReader.UserService.Feed selectedFeed = lbi.SelectedItem as LightReader.UserService.Feed;
                fetchFeed(selectedFeed.Url.AbsoluteUri);
            }          
        }

        void proxy_ImportOPMLCompleted(object sender, ImportOPMLCompletedEventArgs e)
        {
            List<LightReader.LightReaderService.Feed> importedFeeds = e.Result;
            foreach (LightReader.LightReaderService.Feed f in importedFeeds)
            {
                LightReader.UserService.Feed newFeed = new LightReader.UserService.Feed { Name = f.Name, Url = f.Url, Description = f.Description };
                addFeedToList(newFeed);
            }
        }
        #endregion

        #region helper methods
        private void setupExternalServices()
        {
            // snagged this from Shawn Wildermuth's AG Games sample
            // (http://adoguy.com/2008/03/12/Source_Code_Now_Available_for_my_AGGames_Silverlight_2_Example.aspx)
            // Current WCF binding requires to specify this via code as it doesn't read the configuration
            // or setup the reference with the service side bindings correctly (max size)
            BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
            binding.MaxBufferSize = Int32.MaxValue;
            binding.MaxReceivedMessageSize = Int32.MaxValue;

            EndpointAddress lightReaderServiceAddress = new EndpointAddress("http://localhost:4234/LightReader_Web/LightReaderService.svc");
            EndpointAddress userServiceAddress = new EndpointAddress("http://localhost:4234/LightReader_Web/UserService.svc");

            _userServiceProxy = new UserServiceClient(binding, userServiceAddress);
            _lightReaderServiceProxy = new LightReaderServiceClient(binding, lightReaderServiceAddress);
        }

        private void setupEventHandlers()
        {
            // service event handlers
            if (_lightReaderServiceProxy != null)
            {
                _lightReaderServiceProxy.GetFeedCompleted += new EventHandler<GetFeedCompletedEventArgs>(proxy_GetFeedCompleted);
                _lightReaderServiceProxy.ImportOPMLCompleted += new EventHandler<ImportOPMLCompletedEventArgs>(proxy_ImportOPMLCompleted);
            }

            // app event handlers
            App.Current.Host.Content.Resized += (s, e) =>
            {
                subscribeForm.Width = App.Current.Host.Content.ActualWidth;
                subscribeForm.Height = App.Current.Host.Content.ActualHeight;
                postGrid.Height = App.Current.Host.Content.ActualHeight * .75;
            };

            // control event handlers
            subscribeToFeedButton.Click += (s, e) => { subscribePopup.IsOpen = true; };
            subscribeForm.cancelButton.Click += (s, e) => { subscribePopup.IsOpen = false; };
            subscribeForm.SubscriptionAdded += new EventHandler<SubscriptionEventArgs>(subscribeForm_SubscriptionAdded);
            refreshFeedsButton.Click += new RoutedEventHandler(refreshFeedsButton_Click);
            importOPMLButton.Click += new RoutedEventHandler(importOPMLButton_Click);
            myProfileButton.Click += new RoutedEventHandler(myProfileButton_Click);
            logoutButton.Click += new RoutedEventHandler(logoutButton_Click);
            subscribedFeedsList.SelectionChanged += new SelectionChangedEventHandler(subscribedFeedsList_SelectionChanged);
            unsubscribeFromFeedButton.Click += new RoutedEventHandler(unsubscribeFromFeedButton_Click);
        }

        private void loadFeeds()
        {
            if (_user != null)
            {
                subscribedFeedsList.ItemsSource = null;
                subscribedFeedsList.ItemsSource = _user.SubscribedFeeds;
                subscribedFeedsList.DisplayMemberPath = "Name";                
            }
        }

        private void handleFeedData(LightReader.LightReaderService.Feed feedData)
        {
            if (feedData != null)
            {
                blogTitle.Text = "LightReader -";
                blogHyperlinkButton.NavigateUri = feedData.Url;
                blogHyperlinkButton.Content = feedData.Name;
                blogHyperlinkButton.Visibility = Visibility.Visible;
                blogHyperlinkButton.TargetName = "_blank";
                postGrid.ItemsSource = feedData.Items;
            }
        }

        private void fetchFeed(string feedUrl)
        {            
            if (feedUrl.Length > 0)
            {
                _lightReaderServiceProxy.GetFeedAsync(feedUrl);
            }
        }

        private void addFeedToList(LightReader.UserService.Feed feed)
        {
            if (! isSubscribedToFeed(feed))
            {
                List<LightReader.UserService.Feed> subscribedFeeds = _user.SubscribedFeeds.ToList<LightReader.UserService.Feed>();
                subscribedFeeds.Add(feed);
                subscribedFeedsList.ItemsSource = subscribedFeeds;
            }
        }

        private bool isSubscribedToFeed(LightReader.UserService.Feed feed)
        {
            var itemCount = (from LightReader.UserService.Feed f in subscribedFeedsList.Items
                             where f.Url.ToString() == feed.Url.AbsoluteUri
                             select f).Count();

            return (itemCount != 0) ? true : false;
        }

        private void persistFeed(LightReader.UserService.Feed feed)
        {
            // persist...
            _userServiceProxy.SubscribeToFeedAsync(_user, feed.Name, feed.Url.AbsoluteUri);
        }
        #endregion

    }
}
